#ifndef LEXICAL_H
#define LEXICAL_H

#include <iostream>
#include <fstream>
#include <string.h>
#include <cstring>
using namespace std;

#define PRE_PROCESS_DEBUG 0
#define LEX_ANALYZE_DEBUG 0

#define ENTER_BUFFER_SIZE 512
#define SCAN_BUFFER_SIZE 512

extern const char *key_word[8];
enum symbol_type
{
    NOT_KNOW = 0,
    INT,
    FLOAT,
    CHAR,
    STRING
};
// 符号表每一项
struct lex_symbol
{
    char *name;
    symbol_type type;
    char *value;
    lex_symbol *next;

    lex_symbol(char *n, symbol_type t, char *v)
        : name(strdup(n)), type(t), value(strdup(v)), next(nullptr) {}

    ~lex_symbol()
    {
        free(name);
        free(value);
    }
};

// 符号表类
class Symbol_Table
{
private:
    int length;
    lex_symbol *head;

public:
    Symbol_Table() : length(0), head(new lex_symbol((char *)"", NOT_KNOW, (char *)""))
    {

    }

    ~Symbol_Table()
    {
        lex_symbol *current = head;
        while (current != nullptr)
        {
            lex_symbol *next = current->next;
            delete current;
            current = next;
        }
    }

    int symbol_table_add(char *name)
    {
        lex_symbol *new_symbol = new lex_symbol((char *)name, NOT_KNOW, (char *)"");
        lex_symbol *temp = head;
        while (temp->next != nullptr)
        {
            // 检查是否重复
            if (strcmp(temp->next->name, name) == 0)
            {
                
                delete new_symbol;
                return this->length;
            }
            temp = temp->next;
        }
        temp->next = new_symbol;
        return ++this->length;
    }

    void print_symbol()
    {
        std::ofstream file_stream("./inter_txt/symbol_table.txt"); // 创建一个文件流对象
        if (!file_stream.is_open()) {
            perror("Create symbol_table.txt error!");
            return;
        }

        file_stream << "Symbol Table (size: " << this->length << ")\n"
                    << "name\ttype\tvalue\n";

        lex_symbol *temp = head->next;
        while (temp != nullptr) {
            file_stream << temp->name << "\t" << temp->type << "\t" << temp->value << "\n";
            temp = temp->next;
        }

        file_stream.close(); // 关闭文件流
        // cout << "Symbol Table (size: " << this->length << ")\nname\ttype\tvalue\n";
        // lex_symbol *temp = head->next;
        // while (temp != nullptr)
        // {
        //     std::cout << (char *)temp->name << "\t" << temp->type << "\t" << temp->value << "\n";
        //     temp = temp->next;
        // }
    }
};

int preprocess(char *in_file_path, char *out_file_path);
int lex_analyze(char *in_file_path, char *out_file_path, Symbol_Table *my_symbol_table);

#endif